//
//  PhotoVideoViewController.swift
//  PhotoTestDemo
//
//  Created by 惠 on 2020/9/7.
//  Copyright © 2020 惠. All rights reserved.
//

import UIKit
import Photos

@objc public protocol PhotoVideoViewControllerDelegate {
    //mediaType: 1:照片， 2:视频
    func didFinishPhoto(mediaType: Int, images: [UIImage], urls: [URL])
}

public enum SelectType {
    case defaults
    case photo //选择照片
    case camera //拍摄视频
    case picture //选择视频
}

public enum ColorType {
    case defaults
    case red
}

//获取图片
fileprivate class ThisClass {}
public struct Resources {
    public static var getBundle: Bundle {
        let path = Bundle(for: ThisClass.self).resourcePath! + "/PhotoVideo.bundle"
        return Bundle(path: path)!
    }
}

public class PhotoVideoViewController: UIViewController {
    
    //最多选择图片数量
    open var maxSelectPhotoCount: Int = 9
    //最多选择视频数量
    open var maxSelectVideoCount: Int = 1
    //最大录制时间
    open var maxVideoTime: Int = 45
    //最小录制时间
    open var minVideoTime: Int = 5
    //最小照片尺寸
    open var minPhotoSize: Double = 200
    //代理
    open weak var delegate: PhotoVideoViewControllerDelegate?
    private var type: SelectType!
    private var colorType: ColorType!
    private var presetType: String!
    //选择内容
    var selectedAsset: [PHAsset]?
    
    let screenW = UIScreen.main.bounds.width
    let screenH = UIScreen.main.bounds.height
    //选中相册状态
    var selectPhotoButtonStatu: Bool = false

    public init(type: SelectType = .defaults, colorType: ColorType = .defaults, presetType: String = AVAssetExportPreset640x480) {
        super.init(nibName: nil, bundle: nil)
 
        self.type = type
        self.presetType = presetType
        self.colorType = colorType
    
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
    }
    
    public override func viewDidLoad() {
        super.viewDidLoad()

        NotificationCenter.default.addObserver(self, selector: #selector(bottonSelectAction(not:)), name: NSNotification.Name(rawValue: "bottonSelect"), object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(navigationselectAction(not:)), name: NSNotification.Name(rawValue: "navigatorAction"), object: nil)
        
        if type == .camera {
            setUI(index: 1)
            customNav.bottomClearColor(index: 1)
        } else {
            setUI(index: 0)
        }
    }
    
    public override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        
        //获取当前视图frame
//        let viewH = view.frame.height

    }
    
    //MARK: -懒加载UI
    lazy var customNav = CustomNavigatorView()
    
    lazy var bottomSelectView = BottomSelectView(colorType: colorType)
    
    lazy var loadingView = LoadingView(frame: CGRect(origin: CGPoint(x: (screenW-80)/2, y: (screenH-80)/2), size: CGSize(width: 80, height: 80)))
    
    //选择系统照片视频
    lazy var photoVC: PhotoViewController = {
        let photoVC = PhotoViewController()
        photoVC.colorType = colorType
        photoVC.selectedHandler = { [weak self] myAssets in
            guard let self = self else { return }
            if myAssets.count == 0 {
                if self.type != .photo {
                    self.bottomSelectView.swicthBottomView.isHidden = false
                    self.bottomSelectView.selectBottomView.isHidden = true
                }
                self.bottomSelectView.selectedCount.text = "\(myAssets.count)"
            } else {
                self.bottomSelectView.swicthBottomView.isHidden = true
                self.bottomSelectView.selectBottomView.isHidden = false
                if myAssets[0].mediaType.rawValue == 1 {
                    self.bottomSelectView.totalCount.text = "/\(self.maxSelectPhotoCount))"
                } else {
                    self.bottomSelectView.totalCount.text = "/\(self.maxSelectVideoCount))"
                }
                self.bottomSelectView.selectedCount.text = "\(myAssets.count)"
            }
            self.selectedAsset = myAssets
        }
        photoVC.selectedFinishHandler = { [weak self] myAssets in
            guard let self = self else { return }
            if myAssets[0].mediaType.rawValue == 1 {
                var images: [UIImage] = []
                var i = 0
                for myAss in myAssets {
                    //获取原图
                    PHImageManager.default().requestImageData(for: myAss, options: nil) { [weak self](imageData, dataUTI, orientation, info) in
                        guard let self = self else { return }
                        let image = UIImage(data: imageData!)
                        i += 1
                        let fixelW = (image?.cgImage)!.width
                        let fixelH = (image?.cgImage)!.height
                        let fixelMin = Double(min(fixelW, fixelH))
                        let newSize: CGSize?
                        if fixelMin < self.minPhotoSize {
                            //修改照片尺寸
                            let ratio = self.minPhotoSize/fixelMin
                            newSize = CGSize(width: CGFloat(Double(fixelW) * ratio), height: CGFloat(Double(fixelH) * ratio))
                            let rect = CGRect(x: 0, y: 0, width: (newSize?.width)!, height: (newSize?.height)!)
                            UIGraphicsBeginImageContextWithOptions(newSize!, false, 1.0)
                            image?.draw(in: rect)
                            let newImage = UIGraphicsGetImageFromCurrentImageContext()
                            UIGraphicsEndImageContext()
                            
                            images.append(newImage!)
                        } else {
                            images.append(image!)
                        }
                        
                        if i == myAssets.count {
                            self.selectFinishAction(mediaType: 1, images: images)
                        }
                    }
                }
            } else if myAssets[0].mediaType.rawValue == 2 {
                DispatchQueue.main.async { [weak self] in
                    guard let self = self else { return }
                    self.loadingView.isHidden = false
                    self.loadingView.activeView.startAnimating()
                }
                var urls: [URL] = []
                var i = 0
                let options = PHVideoRequestOptions()
                options.version = .original
                for myAss in myAssets {
                    let time = self.getVideotime(videoAsset: myAss)
                    //获取视频
                    PHCachingImageManager().requestAVAsset(forVideo: myAss, options:options, resultHandler: { [weak self](asset, audioMix, info)in
                        guard let self = self else { return }
                        let avAsset = asset as? AVURLAsset
                        let assetUrl = avAsset?.url
                        if time < self.maxVideoTime {
                            self.compressionVideo(url: assetUrl!) { (url) in
                                i += 1
                                urls.append(url)
                                if i == myAssets.count {
                                    self.selectFinishAction(mediaType: 2, serviceVideo: true, urls: urls)
                                }
                            }
                        } else {
                            self.cutVideo(url: assetUrl!, startTime: 0, endTime: TimeInterval(self.maxVideoTime)) { (url1) in
                                self.compressionVideo(url: url1) { (url) in
                                    i += 1
                                    urls.append(url)
                                    if i == myAssets.count {
                                        self.selectFinishAction(mediaType: 2, serviceVideo: true, urls: urls)
                                    }
                                }
                                
                            }
                        }
                    })
                }
            }
        }
        return photoVC
    }()
    
    //拍视频
    lazy var videoVC: VideoViewController = {
        let videoVC = VideoViewController()
        videoVC.colorType = colorType
        videoVC.selecType = type
        videoVC.selectedHandler = { [weak self]url in
            DispatchQueue.main.async {
                self?.loadingView.isHidden = false
                self?.loadingView.activeView.startAnimating()
            }
            self?.compressionVideo(url: url, callBack: { (url1) in
                self?.selectFinishAction(mediaType: 2, urls: [url1])
            })
        }
        return videoVC
    }()

    @available(iOS 10.0, *)
    lazy var takingPicturesVC: TakingPicturesViewController = {
        let takingPicturesVC = TakingPicturesViewController()
        takingPicturesVC.colorType = colorType
        takingPicturesVC.selectedHandler = { [weak self]image in
            guard let self = self else { return }
            let fixelW = (image.cgImage)!.width
            let fixelH = (image.cgImage)!.height
            let fixelMin = Double(min(fixelW, fixelH))
            let newSize: CGSize?
            if fixelMin < 100 {
                //修改照片尺寸
                let ratio = 100.0/fixelMin
                newSize = CGSize(width: CGFloat(Double(fixelW) * ratio), height: CGFloat(Double(fixelH) * ratio))
                let rect = CGRect(x: 0, y: 0, width: (newSize?.width)!, height: (newSize?.height)!)
                UIGraphicsBeginImageContextWithOptions(newSize!, false, 1.0)
                image.draw(in: rect)
                let newImage = UIGraphicsGetImageFromCurrentImageContext()
                UIGraphicsEndImageContext()
                self.selectFinishAction(mediaType: 1, images: [newImage!])
            } else {
                self.selectFinishAction(mediaType: 1, images: [image])
            }
        }
        return takingPicturesVC
    }()
    
    //选择完成返回
    func selectFinishAction(mediaType: Int, serviceVideo: Bool! = nil, images: [UIImage]! = nil, urls: [URL]! = nil) {
        if mediaType == 1 {
            var compressionImages: [UIImage] = []
            images.forEach { image in
                if let imageData: Data = image.jpegData(compressionQuality: 0.3) {
                    compressionImages.append(UIImage(data: imageData) ?? UIImage())
                }
            }
            
            self.dismiss(animated: true, completion: nil)
            self.delegate?.didFinishPhoto(mediaType: mediaType, images: compressionImages, urls: [])
        }else if mediaType == 2 {
            DispatchQueue.main.async { [weak self] in
                guard let self = self else { return }
                self.loadingView.isHidden = true
                self.loadingView.activeView.stopAnimating()
            }
            DispatchQueue.main.async { [weak self] in
                guard let self = self else { return }
                self.dismiss(animated: true, completion: nil)
            }
            self.delegate?.didFinishPhoto(mediaType: mediaType, images: [], urls: urls)
        }
    }
    
    //MARK: -设置UI
    func setUI(index: Int) {
        view.backgroundColor = .white
        
        var bottomH: CGFloat = 50
        //获取底部安全距离
        if #available(iOS 11.0, *) {
            if (UIApplication.shared.keyWindow?.safeAreaInsets.bottom ?? 0) > 0 {
                bottomH += 20
            }
        }
        //状态栏高度
        var statusH: CGFloat = 0
        if #available(iOS 13.0, *) {
            statusH = UIApplication.shared.windows[0].windowScene?.statusBarManager?.statusBarFrame.size.height ?? 20
        } else {
            statusH = UIApplication.shared.statusBarFrame.size.height
        }
        
        if index == 0 {
            removeParentView()
            addChild(photoVC)
            view.addSubview(photoVC.view)
            photoVC.maxSelectVideoCount = maxSelectVideoCount
            photoVC.maxSelectPhotoCount = maxSelectPhotoCount
            photoVC.view.frame = CGRect(origin: CGPoint(x: 0, y: 45+statusH), size: CGSize(width: screenW, height: screenH-45-statusH-bottomH))
        } else if index == 1 {
            removeParentView()
            addChild(videoVC)
            view.addSubview(videoVC.view)
            videoVC.videoTime = maxVideoTime
            videoVC.minTime = minVideoTime
            videoVC.view.frame = CGRect(origin: CGPoint(x: 0, y: 0), size: CGSize(width: screenW, height: screenH))
        } else {
            removeParentView()
            if #available(iOS 10.0, *) {
                addChild(takingPicturesVC)
                view.addSubview(takingPicturesVC.view)
                takingPicturesVC.view.frame = CGRect(origin: CGPoint(x: 0, y: 0), size: CGSize(width: screenW, height: screenH))
            }
        }
        
        view.addSubview(customNav)
        customNav.frame = CGRect(origin: CGPoint(x: 0, y: statusH), size: CGSize(width: screenW, height: 45))
        customNav.backButton.addTarget(self, action: #selector(backButtonAction), for: .touchUpInside)
        customNav.selectPhotoButton.addTarget(self, action: #selector(selectPhotoButtonAction), for: .touchUpInside)
        
        
        view.addSubview(bottomSelectView)
        switch type {
        case .picture:
            bottomSelectView.maxSelectPhotoCount = maxSelectVideoCount
        default:
            bottomSelectView.maxSelectPhotoCount = maxSelectPhotoCount
        }
        bottomSelectView.frame = CGRect(origin: CGPoint(x: 0, y: screenH-bottomH), size: CGSize(width: screenW, height: bottomH))
        bottomSelectView.nextButton.addTarget(self, action: #selector(nextButtonAction), for: .touchUpInside)
        bottomSelectView.alphaButton.addTarget(self, action: #selector(alphaButtonAction), for: .touchUpInside)
        switch self.type {
        case .defaults:
            bottomSelectView.isHidden = false
        case .photo:
            photoVC.type = .photo
//            bottomSelectView.swicthBottomView.isHidden = true
//            bottomSelectView.selectBottomView.isHidden = false
            bottomSelectView.isHidden = false
            bottomSelectView.videoButton.isHidden = true
        case .camera:
            bottomSelectView.isHidden = true
            bottomSelectView.videoButton.isHidden = false
        case .picture:
            photoVC.type = .picture
            bottomSelectView.isHidden = false
            bottomSelectView.selectBottomView.isHidden = false
        default:
            break
        }
        
        self.view.addSubview(loadingView)

    }
    
    func removeParentView() {
        photoVC.view.removeFromSuperview()
        photoVC.removeFromParent()
        videoVC.view.removeFromSuperview()
        videoVC.removeFromParent()
        if #available(iOS 10.0, *) {
            takingPicturesVC.view.removeFromSuperview()
            takingPicturesVC.removeFromParent()
        }
    }
    
    //MARK: -点击事件
    //返回
    @objc func backButtonAction() {
        self.dismiss(animated: true, completion: nil)
    }
    
    //切换相薄类型
    @objc func selectPhotoButtonAction() {
        customNav.selectPhotoButton.isSelected = !selectPhotoButtonStatu
        //显示相薄列表
        photoVC.imageCategoryView.isHidden = selectPhotoButtonStatu
        if !selectPhotoButtonStatu {
            photoVC.imageCategoryView.albumsContent()
        }
        //显示底部阴影视图
        bottomSelectView.alphaButton.isHidden = selectPhotoButtonStatu
        selectPhotoButtonStatu = !selectPhotoButtonStatu
    }
    
    //隐藏底部阴影视图
    @objc func alphaButtonAction() {
        customNav.selectPhotoButton.isSelected = !selectPhotoButtonStatu
        //隐藏相薄列表
        photoVC.imageCategoryView.isHidden = selectPhotoButtonStatu
        selectPhotoButtonStatu = !selectPhotoButtonStatu
        //隐藏底部阴影视图
        bottomSelectView.alphaButton.isHidden = true
    }
    
    //下一步
    @objc func nextButtonAction() {
        if (selectedAsset?.count ?? 0) > 0 {
            if selectedAsset?[0].mediaType.rawValue == 1 {
                var images: [UIImage] = []
                var i = 0
                for myAss in selectedAsset! {
                    //获取原图
                    PHImageManager.default().requestImageData(for: myAss, options: nil) { [weak self](imageData, dataUTI, orientation, info) in
                        guard let self = self else { return }
                        let image = UIImage(data: imageData!)
                        i += 1
                        let fixelW = (image?.cgImage)!.width
                        let fixelH = (image?.cgImage)!.height
                        let fixelMin = Double(min(fixelW, fixelH))
                        let newSize: CGSize?
                        if fixelMin < self.minPhotoSize {
                            //修改照片尺寸
                            let ratio = self.minPhotoSize/fixelMin
                            newSize = CGSize(width: CGFloat(Double(fixelW) * ratio), height: CGFloat(Double(fixelH) * ratio))
                            let rect = CGRect(x: 0, y: 0, width: (newSize?.width)!, height: (newSize?.height)!)
                            UIGraphicsBeginImageContextWithOptions(newSize!, false, 1.0)
                            image?.draw(in: rect)
                            let newImage = UIGraphicsGetImageFromCurrentImageContext()
                            UIGraphicsEndImageContext()
                            
                            images.append(newImage!)
                        } else {
                            images.append(image!)
                        }
                        
                        if i == self.selectedAsset?.count {
                            self.selectFinishAction(mediaType: 1, images: images)
                        }
                    }
                }
            } else if selectedAsset?[0].mediaType.rawValue == 2 {
                DispatchQueue.main.async { [weak self] in
                    guard let self = self else { return }
                    self.loadingView.isHidden = false
                    self.loadingView.activeView.startAnimating()
                }
                var urls: [URL] = []
                var i = 0
                for myAss in selectedAsset! {
                    let time = self.getVideotime(videoAsset: myAss)
                    //获取视频
                    PHCachingImageManager().requestAVAsset(forVideo: myAss, options:nil, resultHandler: { [weak self](asset, audioMix, info)in
                        guard let self = self else { return }
                        let avAsset = asset as? AVURLAsset
                        let assetUrl = avAsset?.url
                        if time < self.maxVideoTime {
                            self.compressionVideo(url: assetUrl!) { (url) in
                                i += 1
                                urls.append(url)
                                if i == self.selectedAsset?.count {
                                    self.selectFinishAction(mediaType: 2, serviceVideo: true, urls: urls)
                                }
                            }
                        } else {
                            self.cutVideo(url: assetUrl!, startTime: 0, endTime: TimeInterval(self.maxVideoTime)) { (url1) in
                                self.compressionVideo(url: url1) { (url) in
                                    i += 1
                                    urls.append(url)
                                    if i == self.selectedAsset?.count {
                                        self.selectFinishAction(mediaType: 2, serviceVideo: true, urls: urls)
                                    }
                                }
                            }
                        }
                        
                    })
                }
            }
        }
    }
    
    //MARK: -通知
    //底部按钮事件
    @objc func bottonSelectAction(not: Notification) {
        //选择类型
        if let index = not.userInfo!["index"] as? Int {
            setUI(index: index)
            customNav.bottomClearColor(index: index)
        }
        
        //选择相薄照片类型
        if let item = not.userInfo!["asset"] as? AlbumItem {
            //设置导航栏相册类型标题
            customNav.selectPhotoButton.setTitle(item.title, for: .normal)
            customNav.selectPhotoButton.isSelected = !selectPhotoButtonStatu
            //隐藏相薄列表
            photoVC.imageCategoryView.isHidden = selectPhotoButtonStatu
            selectPhotoButtonStatu = !selectPhotoButtonStatu
            //隐藏底部阴影视图
            bottomSelectView.alphaButton.isHidden = true
        }
        
        if let item = not.userInfo!["asset1"] as? Int {
            if item == 1 {
                customNav.selectPhotoButton.isSelected = !selectPhotoButtonStatu
                //隐藏底部阴影视图
                bottomSelectView.alphaButton.isHidden = true
                
                selectPhotoButtonStatu = !selectPhotoButtonStatu
            }
        }
        
        //隐藏底部视图
        if let hidden = not.userInfo!["hidden"] as? Int {
            bottomSelectView.isHidden = hidden == 1 ? true : false
        }
    }
    
    //导航栏事件
    @objc func navigationselectAction(not: Notification) {
        //闪光灯
        if let index = not.userInfo!["index"] as? Int {
            if #available(iOS 10.0, *) {
                takingPicturesVC.isFlash = index == 1 ? .on : .off
            }
            try? videoVC.videoDevice?.lockForConfiguration()
            videoVC.videoDevice?.torchMode = index == 1 ? .on : .off
            videoVC.videoDevice?.unlockForConfiguration()
        }
        //切换摄像头
        if let camear = not.userInfo!["camera"] as? Int {
            if #available(iOS 10.0, *) {
                takingPicturesVC.switchCamera(position: (camear == 1 ? .back : .front))
            }
            videoVC.switchCamera(position: (camear == 1 ? .back : .front))
        }
    }
    
    deinit {
        NotificationCenter.default.removeObserver(self)
    }
}

//MARk: -视频相关处理
extension PhotoVideoViewController {
    
    //将mov转mp4
    func swicthModel(outputFileURL: URL) -> URL {
        let avAsset = AVURLAsset.init(url: outputFileURL, options: nil)
        
        let destinationPath = NSTemporaryDirectory() + "fileName.mp4"
        let newVideoPath: NSURL = NSURL(fileURLWithPath: destinationPath as String)
        let exporter = AVAssetExportSession(asset: avAsset,
                                            presetName:AVAssetExportPresetHighestQuality)!
        exporter.outputURL = newVideoPath as URL
        exporter.outputFileType = AVFileType.mp4
        exporter.shouldOptimizeForNetworkUse = true
        exporter.exportAsynchronously(completionHandler: {
            print("NewPath：\(String(describing: newVideoPath.relativePath))")
        })
        return URL(fileURLWithPath: newVideoPath.relativePath!)
    }
    
    //获取视频文件的时长
    func getVideotime(videoAsset: PHAsset) -> Int {
        let duration: TimeInterval = videoAsset.duration
        return Int(duration)
    }
    
    //剪切视频
    func  cutVideo(url: URL, startTime: TimeInterval, endTime: TimeInterval, callBack:  @escaping(URL)->()) {
        //根据视频路径来创建asset
        let asset = AVURLAsset(url: url)
        //创建一个轨道级检查界面的对象
        let videoAssetTrack = asset.tracks(withMediaType: .video).first! //视频轨迹
        let audioAssetTrack = asset.tracks(withMediaType: .audio).first! //音频轨迹
        //1创建一个AVMutableComposition,将视频插入视频轨道，音频插入音频轨道
        let composition = AVMutableComposition()
        //2 创建一个音频和视频的轨道,类型都为AVMediaTypeAudio
        let videoTrack = composition.addMutableTrack(withMediaType: .video, preferredTrackID: kCMPersistentTrackID_Invalid)
        videoTrack?.preferredTransform = videoAssetTrack.preferredTransform
        //获取videoPath的音视频插入轨道
        try? videoTrack?.insertTimeRange(CMTimeRangeMake(start: CMTime.zero, duration: asset.duration), of: videoAssetTrack, at: CMTime.zero)
        
        let audioTrack = composition.addMutableTrack(withMediaType: .audio, preferredTrackID: kCMPersistentTrackID_Invalid)
        try? audioTrack?.insertTimeRange(CMTimeRangeMake(start: CMTime.zero, duration: asset.duration), of: audioAssetTrack, at: CMTime.zero)
        
        //3.裁剪视频，就是要将所有的视频轨道进行裁剪，就需要得到所有的视频轨道，而得到一个视频轨道就需要得到它上面的所有素材
        let layerInstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: videoTrack!)
        layerInstruction.setOpacity(0.0, at: (videoTrack?.asset?.duration)!)

        let instrucation = AVMutableVideoCompositionInstruction()
        instrucation.timeRange = CMTimeRangeMake(start: CMTime.zero, duration: (videoTrack?.asset?.duration)!)
        instrucation.layerInstructions = [layerInstruction]
        
        let mainConposition = AVMutableVideoComposition()
        mainConposition.instructions = [instrucation]
        mainConposition.frameDuration = CMTimeMake(value: 1, timescale: Int32(maxVideoTime))
        mainConposition.renderSize = CGSize(width: (videoTrack?.naturalSize.width)!, height: (videoTrack?.naturalSize.height)!)
        
        //导出视频
        let start = CMTimeMakeWithSeconds(startTime, preferredTimescale: asset.duration.timescale)
        let duration = CMTimeMakeWithSeconds(endTime-startTime, preferredTimescale: asset.duration.timescale)
        
        let range = CMTimeRangeMake(start: start, duration: duration)
        
        let session = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetHighestQuality)
        session?.videoComposition = mainConposition
        session?.outputURL = filePathWithFileName(fileName: "/cutfileName.mp4")
        session?.outputFileType = .mp4
        session?.shouldOptimizeForNetworkUse = true
        session?.timeRange = range
        session?.exportAsynchronously {
            if session?.status.rawValue == 3 {
                callBack((session?.outputURL)!)
            } else {
                print(session?.error as Any)
                DispatchQueue.main.async { [weak self] in
                    guard let self = self else { return }
                    self.loadingView.isHidden = true
                    self.loadingView.activeView.stopAnimating()
                    
                    let alertVC = UIAlertController(title: "视频处理失败", message: nil, preferredStyle: .alert)
                    alertVC.addAction(UIAlertAction(title: "重选", style: .destructive, handler: { (alert) in
                        alertVC.dismiss(animated: true, completion: nil)
                    }))
                    alertVC.addAction(UIAlertAction(title: "返回", style: .cancel, handler: { (alert) in
                        alertVC.dismiss(animated: true, completion: nil)
                        self.dismiss(animated: true, completion: nil)
                    }))
                    self.present(alertVC, animated: true, completion: nil)
                }
            }
            
        }
    }
    
    //压缩视频
    func compressionVideo(url: URL, callBack: @escaping(URL)->()) {
        //1.获取本地视频，fromUrl为本地视频链接
        let asset = AVAsset(url: url)
        //2.压缩视频
        //(1)初始化视频资源导出会话
        let session = AVAssetExportSession(asset: asset, presetName: self.presetType)
        //(2)设置压缩后属性
        // 设置导出的视频位置toUrl
        //        let destinationPath = NSTemporaryDirectory() + "fileName.mp4"
        //        let newVideoPath: NSURL = NSURL(fileURLWithPath: destinationPath as String)
        session?.outputURL = filePathWithFileName(fileName: "/fileName.mp4")
        //设置导出的视频格式(必须设置)
        session?.outputFileType = .mp4
        session?.shouldOptimizeForNetworkUse = true
        session?.videoComposition = getVideoComposition(asset: asset)
        //(3)开始压缩
        session?.exportAsynchronously {
            if session?.status.rawValue == 3 {
                callBack((session?.outputURL)!)
            } else {
                DispatchQueue.main.async { [weak self] in
                    guard let self = self else { return }
                    self.loadingView.isHidden = true
                    self.loadingView.activeView.stopAnimating()
                    
                    let alertVC = UIAlertController(title: "视频处理失败", message: nil, preferredStyle: .alert)
                    alertVC.addAction(UIAlertAction(title: "重选", style: .destructive, handler: { (alert) in
                        alertVC.dismiss(animated: true, completion: nil)
                    }))
                    alertVC.addAction(UIAlertAction(title: "返回", style: .cancel, handler: { (alert) in
                        alertVC.dismiss(animated: true, completion: nil)
                        self.dismiss(animated: true, completion: nil)
                    }))
                    self.present(alertVC, animated: true, completion: nil)
                }
            }
        }
    }
    
    //获取地址
    func filePathWithFileName(fileName: String) -> URL {
        var tempPath = NSTemporaryDirectory()
        tempPath = tempPath.appending("Video")
        let manager = FileManager.default
        if !manager.fileExists(atPath: tempPath) {
            try? manager.createDirectory(atPath: tempPath, withIntermediateDirectories: true, attributes: nil)
        }
        tempPath = tempPath.appending(fileName)
        if manager.fileExists(atPath: tempPath) {
            try? manager.removeItem(atPath: tempPath)
        }
        return URL(fileURLWithPath: tempPath)
    }
    
    //获取文件大小
    func getFileSize(path: String) -> Double {
        var tempPath = NSTemporaryDirectory().appending("Video")
        tempPath = tempPath.appending(path)
        if let filedata = try? Data(contentsOf: URL(fileURLWithPath: tempPath)) {
            let size = Double(filedata.count)/1024/1024
            return size
        }
        return 0
    }
    
    //设置视频方向大小
    func getVideoComposition(asset: AVAsset) -> AVMutableVideoComposition {
        let videoTrack = asset.tracks(withMediaType: .video).first
        let composition = AVMutableComposition()
        let videoComposition = AVMutableVideoComposition(propertiesOf: composition)
        var videoSize = videoTrack?.naturalSize
        let tracks = asset.tracks(withMediaType: .video)
        if tracks.count > 0 {
            let videoTrack1 = tracks[0]
            let t = videoTrack1.preferredTransform
            if (t.a == 0 && t.b == 1.0 && t.c == -1.0 && t.d == 0) || (t.a == 0 && t.b == -1.0 && t.c == 1.0 && t.d == 0) {
                videoSize = CGSize(width: videoSize!.height, height: videoSize!.width)
            }
        }
        composition.naturalSize = videoSize!
        videoComposition.renderSize = videoSize!
        videoComposition.frameDuration = CMTimeMake(value: 1, timescale: 30)
        
        let compositionVideoTrack = composition.addMutableTrack(withMediaType: .video, preferredTrackID: kCMPersistentTrackID_Invalid)
        try? compositionVideoTrack?.insertTimeRange(CMTimeRangeMake(start: CMTime.zero, duration: asset.duration), of: videoTrack!, at: CMTime.zero)
        let layerInst = AVMutableVideoCompositionLayerInstruction(assetTrack: videoTrack!)
        layerInst.setTransform(videoTrack!.preferredTransform, at: CMTime.zero)
        let inst = AVMutableVideoCompositionInstruction()
        inst.timeRange = CMTimeRangeMake(start: CMTime.zero, duration: asset.duration)
        inst.layerInstructions = [layerInst]
        videoComposition.instructions = [inst]
        return videoComposition
    }
    
    //获取视频的方向
    func getDegressWhitURL(url: URL) {
        var degress = 0
        let asset = AVAsset(url: url)
        let tracks = asset.tracks(withMediaType: .video)
        if tracks.count > 0 {
            let videoTrack = tracks[0]
            let t = videoTrack.preferredTransform
            if t.a == 0 && t.b == 1.0 && t.c == -1.0 && t.d == 0 {
                degress = 90
            } else if t.a == 0 && t.b == -1.0 && t.c == 1.0 && t.d == 0 {
                degress = 270
            } else if t.a == 1.0 && t.b == 0 && t.c == 0 && t.d == 1.0 {
                degress = 0
            } else if t.a == -1.0 && t.b == 0 && t.c == 0 && t.d == -1.0 {
                degress = 180
            }
        }
        print(degress)
    }

}
